package com.swu.pad.assignment.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.swu.pad.activity.dao.ActivityDao;
import com.swu.pad.activity.dao.ActivityGroupVisionDao;
import com.swu.pad.activity.entity.Activity;
import com.swu.pad.activity.service.ActivityService;
import com.swu.pad.assignment.dao.AssignmentDao;
import com.swu.pad.assignment.dao.AssignmentPadDao;
import com.swu.pad.assignment.dao.AssignmentScoreDao;
import com.swu.pad.assignment.entity.Assignment;
import com.swu.pad.assignment.entity.AssignmentPad;
import com.swu.pad.assignment.service.AssignmentService;
import com.swu.pad.comment.dao.CommentDao;
import com.swu.pad.course.dao.CourseGroupUserDao;
import com.swu.pad.course.dao.GroupDao;
import com.swu.pad.course.entity.CourseGroupUser;
import com.swu.pad.course.entity.Group;
import com.swu.pad.util.EPLiteClient.EPLiteClient;

@Service
@Transactional
public class AssignmentServiceImpl implements AssignmentService {

	@Autowired
	private GroupDao groupDao;
	@Autowired
	private CommentDao commentDao;
	@Autowired
	private ActivityDao activityDao;
	@Autowired
	private ActivityGroupVisionDao activityGroupVisionDao;
	@Autowired
	private AssignmentDao assignmentDao;
	@Autowired
	private AssignmentPadDao assignmentPadDao;
	@Autowired
	private AssignmentScoreDao assignmentScoreDao;
	@Autowired
	private CourseGroupUserDao courseGroupUserDao;
	@Autowired
	private ActivityService activityService;
	@Autowired
	private EPLiteClient epliteClient;

	public Assignment addAssignment(Assignment assignment) {
		assignment = assignmentDao.saveAndFlush(assignment);
		List<Group> groupList = null;
		if (Assignment.TYPE_SINGLE.equals(assignment.getAssignmentType())) {
			groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_SINGLE);
		} else {
			groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_GROUP);
		}
		for (int i = 0; i < groupList.size(); i++) {
			Group group = groupList.get(i);
			AssignmentPad assignmentPad = new AssignmentPad();
			assignmentPad.setAssignmentId(assignment.getId());
			assignmentPad.setAssignmentName(assignment.getAssignmentName());
			assignmentPad.setCreateTime(new Date());
			assignmentPad.setGroupId(group.getId());
			assignmentPad.setGroupName(group.getGroupName());
			Map<?, ?> map = epliteClient.createGroupPad(assignmentPad.getGroupId(), assignmentPad.getAssignmentName(), assignment.getAssignmentContent());
			epliteClient.setPublicStatus(group.getId()+"$"+assignmentPad.getAssignmentName(), true);
			assignmentPad.setId(map.get("padID").toString());
			assignmentPadDao.saveAndFlush(assignmentPad);
		}
		return assignment;
	}

	public Assignment updateAssignment(Assignment assignment) {
		Assignment oldAssignment = assignmentDao.findOne(assignment.getId());
		if (!oldAssignment.getAssignmentType().equals(assignment.getAssignmentType())) {
			List<AssignmentPad> assignmentPadList = assignmentPadDao.findAssignmentPadByAssignmentId(oldAssignment.getId());
			for (int i = 0; i < assignmentPadList.size(); i++) {
				assignmentScoreDao.deleteByAssignmentPadId(assignmentPadList.get(i).getId());
				commentDao.deleteByAssignmentPadId(assignmentPadList.get(i).getId());
				epliteClient.deletePad(assignmentPadList.get(i).getId());
				assignmentPadDao.delete(assignmentPadList.get(i));
			}
			List<Group> groupList = null;
			if (Assignment.TYPE_SINGLE.equals(assignment.getAssignmentType())) {
				groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_SINGLE);
			} else {
				groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_GROUP);
			}
			for (int i = 0; i < groupList.size(); i++) {
				Group group = groupList.get(i);
				AssignmentPad assignmentPad = new AssignmentPad();
				assignmentPad.setAssignmentId(assignment.getId());
				assignmentPad.setAssignmentName(assignment.getAssignmentName());
				assignmentPad.setCreateTime(new Date());
				assignmentPad.setGroupId(group.getId());
				assignmentPad.setGroupName(group.getGroupName());
				Map<?, ?> map = epliteClient.createGroupPad(assignmentPad.getGroupId(), assignmentPad.getAssignmentName(), assignment.getAssignmentContent());
				epliteClient.setPublicStatus(map.get("padID").toString(), true);
				assignmentPad.setId(map.get("padID").toString());
				assignmentPadDao.saveAndFlush(assignmentPad);
			}
		}
		if (!oldAssignment.getAssignmentContent().equals(assignment.getAssignmentContent())) {
			List<Group> groupList = null;
			if (Assignment.TYPE_SINGLE.equals(assignment.getAssignmentType())) {
				groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_SINGLE);
			} else {
				groupList = groupDao.findGroupByCourseIdAndGroupType(assignment.getCourseId(), Group.TYPE_GROUP);
			}
			for (int i = 0; i < groupList.size(); i++) {
				AssignmentPad assignmentPad = assignmentPadDao.findAssignmentPadByAssignmentIdAndGroupId(oldAssignment.getId(), groupList.get(i).getId());
				epliteClient.setText(assignmentPad.getId(), assignment.getAssignmentContent());
			}
		}
		assignmentDao.saveAndFlush(assignment);
		return assignment;
	}

	@Transactional(rollbackFor = Exception.class)
	public void deleteAssignment(String assignmentId) {
		// 删除作业，同时删除assignmentPad(etherpad中的pad),assignmentScore,comment activity,activityGroupVision
		List<AssignmentPad> assignmentPadList = assignmentPadDao.findAssignmentPadByAssignmentId(assignmentId);
		for (int i = 0; i < assignmentPadList.size(); i++) {
			assignmentScoreDao.deleteByAssignmentPadId(assignmentPadList.get(i).getId());
			commentDao.deleteByAssignmentPadId(assignmentPadList.get(i).getId());
			epliteClient.deletePad(assignmentPadList.get(i).getId());
			assignmentPadDao.delete(assignmentPadList.get(i));
		}
		List<Activity> activityList = activityDao.findActivityByAssignmentId(assignmentId);
		for (int i = 0; i < activityList.size(); i++) {
			activityGroupVisionDao.deleteByActivityId(activityList.get(i).getId());
			activityDao.delete(activityList.get(i));
		}
		assignmentDao.delete(assignmentId);
	}

	public List<Assignment> getAssignmentByCourseId(String courseId) {
		return assignmentDao.findAssignmentByCourseId(courseId);
	}

	public Assignment getAssignment(String assignmentId) {
		return assignmentDao.findOne(assignmentId);
	}

	public Map<String, Object> getAssignmentDetail(String assignmentId) {
		// {assignment:{},assignmentPad:[]}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("assignment", assignmentDao.findOne(assignmentId));
		map.put("assignmentPad", assignmentPadDao.findAssignmentPadByAssignmentId(assignmentId));
		return map;
	}

	public AssignmentPad getUserAssignmentPad(String assignmentId, String groupId) {
		AssignmentPad assignmentPad = assignmentPadDao.findAssignmentPadByAssignmentIdAndGroupId(assignmentId, groupId);
		return assignmentPad;
	}

	public CourseGroupUser getUserAssignmentSession(String assignmentId, String userId) {
		Assignment assignment = assignmentDao.findOne(assignmentId);
		CourseGroupUser courseGroupUser = null;
		if (Assignment.TYPE_SINGLE.equals(assignment.getAssignmentType())) {
			courseGroupUser = courseGroupUserDao.findCourseGroupUserByCourseIdAndUserIdAndGroupType(assignment.getCourseId(), userId, Group.TYPE_SINGLE);
		} else {
			courseGroupUser = courseGroupUserDao.findCourseGroupUserByCourseIdAndUserIdAndGroupType(assignment.getCourseId(), userId, Group.TYPE_GROUP);
		}
		return courseGroupUser;
	}

	public String getAssignmentPadCurrentId(String assignmentId, String groupId) {
		AssignmentPad assignmentPad = assignmentPadDao.findAssignmentPadByAssignmentIdAndGroupId(assignmentId, groupId);
		return assignmentPad != null ? assignmentPad.getId() : "";
	}

	public Map<String, Object> getCommentAssignmentPad(String activityId, String userId) {
		return activityService.getCommentAssignmentPad(activityId, userId);
	}

}
